package org.fing.edu.uy.esbadp.init;

import java.io.File;
import java.net.URL;
import java.util.logging.Level;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.fing.edu.uy.esbadp.core.constants.EsbAdpPropertyConstants;
import org.fing.edu.uy.esbadp.core.entity.DMAdpConfigProperties;
import org.fing.edu.uy.esbadp.core.entity.DMAdpMonitorMechanism;
import org.fing.edu.uy.esbadp.core.entity.DMAdpMonitorMechanisms;
import org.fing.edu.uy.esbadp.core.entity.DMAdpMonitorProperties;
import org.fing.edu.uy.esbadp.core.entity.DMAdpMonitorProperty;
import org.fing.edu.uy.esbadp.core.entity.DMAdpServiceRequirements;
import org.fing.edu.uy.esbadp.core.entity.DMAdpServices;
import org.fing.edu.uy.esbadp.core.registry.RegistryManager;
import org.fing.edu.uy.esbadp.logger.LoggerADP;

public class AdpConfigurationLoader {
	
	private static java.util.logging.Logger logger = LoggerADP.getLogger(AdpConfigurationLoader.class.getSimpleName());

	public void registerAdpAction() {
		logger.info("Loading Adaptative services");
		try {			
			String path = EsbAdpPropertyConstants.SERVICES_DEF_PATH ;  
			URL url = new URL(path);  	
			File actiondef = new File(url.toURI());
			if(actiondef.exists()) {  
				JAXBContext context = JAXBContext.newInstance(DMAdpServices.class);
				Unmarshaller u = context.createUnmarshaller();
				DMAdpServices adpActions = (DMAdpServices) u.unmarshal(actiondef);			
				logger.info(adpActions.toString());
				
				//Seteo los servicios cargadas.
				RegistryManager.getInstance().setAdpServices(adpActions);				
				
			} else {  
				logger.log(Level.SEVERE, "Actions definition file not found ( " +  EsbAdpPropertyConstants.SERVICES_DEF_PATH  + ")");
			}  
		} catch (Exception ex) {
			logger.log(Level.SEVERE, "Exception registering adp Actions \nSee StackTarce => [ {0} ]", ExceptionUtils.getStackTrace(ex));
		}
	}
	
	public void registerAdpServiceRequirements() {
		logger.info("Loading Adaptative Service Requirements");
		try {
			String path = EsbAdpPropertyConstants.REQUIREMENTS_DEF_PATH ;  			
			URL url = new URL(path);  			
			File actiondef = new File(url.toURI());		
			if(actiondef.exists()) {  				
				JAXBContext context = JAXBContext.newInstance(DMAdpServiceRequirements.class);
				Unmarshaller u = context.createUnmarshaller();
				DMAdpServiceRequirements adpServiceRequirements = (DMAdpServiceRequirements) u.unmarshal(actiondef);			
				logger.info(adpServiceRequirements.toString());
				
				//Seteo los requerimientos de servicios cargados
				RegistryManager.getInstance().setAdpServiceRequirements(adpServiceRequirements);
			} else {  
				logger.log(Level.SEVERE, "Strategies definition file not found ( " + EsbAdpPropertyConstants.REQUIREMENTS_DEF_PATH  + ")");
			}  
		
		} catch (Exception ex) {
			logger.log(Level.SEVERE, "Exception registering adp Requirements \nSee StackTarce => [ {0} ]", ExceptionUtils.getStackTrace(ex));
		}
	}
	
	public void registerAdpMonitorMechanism() {
		logger.info("Loading Monitor Mechanism");
		try {
			
			String path = EsbAdpPropertyConstants.MONITORS_MECHANISM_DEF_PATH ;  			
			URL url = new URL(path);  			
			File actiondef = new File(url.toURI());		
			if(actiondef.exists()) {  				
				JAXBContext context = JAXBContext.newInstance(DMAdpMonitorMechanisms.class);
				Unmarshaller u = context.createUnmarshaller();
				DMAdpMonitorMechanisms adpMonitorMechanism = (DMAdpMonitorMechanisms) u.unmarshal(actiondef);	
				logger.info(adpMonitorMechanism.toString());
				
				//Seteo los mecanismos leidos.
				RegistryManager.getInstance().setAdpMonitorMechanism(adpMonitorMechanism);
				
				//Pruebo que tengo visibilidad a todas las clases. ( ver esto si lo dejamos )
				for(DMAdpMonitorMechanism aux : adpMonitorMechanism.getMechanisms()){
					Class.forName(aux.getClassName());
				}
				
			} else {  
				logger.log(Level.SEVERE, "Monitor mechanism definition file not found ( " + EsbAdpPropertyConstants.MONITORS_MECHANISM_DEF_PATH +")");
			}  
		
		} catch (Exception ex) {
			logger.log(Level.SEVERE, "Exception registering adp Monitor mechanism \nSee StackTarce => [ {0} ]", ExceptionUtils.getStackTrace(ex));
		}
	}
	
	public void registerAdpMonitorProperties() {
		logger.info("Loading Monitor Properties");
		try {
			
			String path = EsbAdpPropertyConstants.PROPERTIES_DEF_PATH ;  			
			URL url = new URL(path);  			
			File actiondef = new File(url.toURI());		
			if(actiondef.exists()) {  				
				JAXBContext context = JAXBContext.newInstance(DMAdpMonitorProperties.class);
				Unmarshaller u = context.createUnmarshaller();
				DMAdpMonitorProperties adpMonitorProperties = (DMAdpMonitorProperties) u.unmarshal(actiondef);	
				logger.info(adpMonitorProperties.toString());
				
				//Seteo los mecanismos leidos.
				RegistryManager.getInstance().setAdpMonitorProperties(adpMonitorProperties);
				
				//Pruebo que tengo visibilidad a todas las clases. ( ver esto si lo dejamos )
				for(DMAdpMonitorProperty aux : adpMonitorProperties.getProperties()){
					Class.forName(aux.getClassName());
				}
				
			} else {  
				logger.log(Level.SEVERE, "Monitor properties definition file not found ( " + EsbAdpPropertyConstants.PROPERTIES_DEF_PATH +")");
			}  
		
		} catch (Exception ex) {
			logger.log(Level.SEVERE, "Exception registering adp Monitor properties \nSee StackTarce => [ {0} ]", ExceptionUtils.getStackTrace(ex));
		}
	}

	public void loadConfigProperties() {
		logger.info("Loading Adp Config Properties");
		try {
			
			String path = EsbAdpPropertyConstants.CONFIG_PROPERTIES_DEF_PATH ;  			
			URL url = new URL(path);  			
			File actiondef = new File(url.toURI());		
			if(actiondef.exists()) {  				
				JAXBContext context = JAXBContext.newInstance(DMAdpConfigProperties.class);
				Unmarshaller u = context.createUnmarshaller();
				DMAdpConfigProperties adpMonitorProperties = (DMAdpConfigProperties) u.unmarshal(actiondef);	
				logger.info(adpMonitorProperties.toString());
				
				//guardo las propiedades de configuracion leidas.
				RegistryManager.getInstance().setAdpConfigProperties(adpMonitorProperties);	
				
			} else {  
				logger.log(Level.SEVERE, "Config properties definition file not found ( " + EsbAdpPropertyConstants.CONFIG_PROPERTIES_DEF_PATH +")");
			}  
		
		} catch (Exception ex) {
			logger.log(Level.SEVERE, "Exception laoding adp Config Properties \nSee StackTarce => [ {0} ]", ExceptionUtils.getStackTrace(ex));
		}
		
	}
	
}
